import { generateAccessToken, refreshToken, httpRequest } from "./src/open-api.js"
// import { getDianPuList,getListingBySid,getSaleBySid,getUserInfo,getAuthToken,syncLingXingSales}from  './src/need-api.js'
 import { getDianPuList,getListingBySid,getSaleBySid,getUserInfo,getAuthToken,syncLingXingSales}from  './src/mock-api.js'

import express from 'express';
import fs from 'fs/promises';
import cron from 'node-cron';
import dayjs from 'dayjs';
import bodyParser from 'body-parser';
import cors from 'cors';
const jsonParser = bodyParser.json();
const app = express();
// 在使用其他中间件之前引入 cors
app.use(cors());
app.use(jsonParser);
// 获取今天的日期
const today = dayjs().format('YYYY-MM-DD');
// 文件路径
const filePath = './config.json';

// 读取文件中的数据
function readData() {
    return new Promise(async (resolve, reject) => {
        try {
            const data = await fs.readFile(filePath, 'utf8');
            resolve(JSON.parse(data));
        } catch (error) {
            console.error("读取文件时发生错误:", error);
            reject(error);
        }
    });
}
/**
 * 获取指定日期的销售数据，并组装成指定格式的数据对象数组。
 * @param {string} date - 需要获取数据的日期，格式为 YYYY-MM-DD。
 * @param {Object} thirdParty - 第三方应用信息。
 * @param {Object} data - 包含访问令牌等数据的对象。
 * @param {Array} allDianPuListInfo - 包含所有店铺信息的数组。
 * @param {Array} userInfo - 用户信息数组，包含用户UID和手机号等信息。
 * @returns {Promise<Array>} 返回一个包含所有店铺在指定日期的销售数据的数组。
 */
async function fetchDataForDate(date, thirdParty, data, allDianPuListInfo, userInfo) {
    const returnData = [];
    console.log(allDianPuListInfo);
    
    for (const element of allDianPuListInfo) {
        // 获取店铺下的所有listing
        const allListingBySid = await getListingBySid(thirdParty.appId, data, element.sid);

        // 获取该店铺下所有listing的销售额
        const currentDataSale = await getSaleBySid(thirdParty.appId, data, element.sid, date);

        currentDataSale.forEach((saleItem) => {
            const obj = {
                asin: saleItem.asin,
                sale: saleItem.map_value,
                date: date,
                currencyCode:saleItem.currency_code
            };
            // 通过 ASIN 匹配 listing 的负责人信息
            const manager = allListingBySid.find(item => item.asin === saleItem.asin)?.principal_info[0];
            if (manager) {
                obj.principal_uid = manager.principal_uid;
                obj.principal_name = manager.principal_name;
            }
            // 根据 UID 匹配用户的手机号
            const userPhone = userInfo.find(item => item.principal_uid === obj.principal_uid)?.mobile;
            if (userPhone) {
                obj.phone = userPhone;
            }
            returnData.push(obj);
        });
    }

    return returnData;
}

// 调用第三方 API 的函数
async function callThirdPartyApi(thirdParty) {
    // 根据appId和appSecret获取access-token和refresh-token
    const data = await generateAccessToken(thirdParty.appId, thirdParty.appSecret);
    // const data = "aaaa"
    
    // 获取所有店铺的信息

    const allDianPuListInfo = await getDianPuList(thirdParty.appId, data);
    console.log(allDianPuListInfo);
    
    // 获取所有的用户信息
    const userInfo = await getUserInfo(thirdParty.appId, data);

    // 获取今天的日期
    const today = dayjs().format('YYYY-MM-DD');
    const yesterday = dayjs().subtract(1, 'day').format('YYYY-MM-DD');
    const dayBeforeYesterday = dayjs().subtract(2, 'day').format('YYYY-MM-DD');

    // 初始化一个空数组用于存储三天的数据
    const combinedData = [];

    // 获取今天、昨天和前天的数据，并将它们合并到一个数组中
    const todayData = await fetchDataForDate(today, thirdParty, data, allDianPuListInfo, userInfo);
    combinedData.push(...todayData); // 将今天的数据添加到combinedData

    const yesterdayData = await fetchDataForDate(yesterday, thirdParty, data, allDianPuListInfo, userInfo);
    combinedData.push(...yesterdayData); // 将昨天的数据添加到combinedData

    const dayBeforeYesterdayData = await fetchDataForDate(dayBeforeYesterday, thirdParty, data, allDianPuListInfo, userInfo);
    combinedData.push(...dayBeforeYesterdayData); // 将前天的数据添加到combinedData
    // 返回合并后的结果
    return combinedData;
}

// 根据返回的数据调用 I.T.A. API 的示例函数
async function callItaApi(ita, data) {
    // 这里替换为实际的 API 调用
    const access_token =await getAuthToken(ita.appId,ita.itaSecret)
    const response = await syncLingXingSales(access_token,data)
    // 直接打印对象
    // console.log(`Calling I.T.A. API with appId: ${ita.appId} and data:`);
    if(response==='没有访问权限'){
        console.log("同步失败:",response);
    }
    else{
        console.log("同步成功");
    }
}

// 启动定时任务
// 启动定时任务
async function scheduleTasks(config) {
    // 定义周期映射表
    const CYCLE_MAP = {
        'daily': '0 0 * * *',
        '每天': '0 0 * * *',
        'monday': '0 0 * * 1',
        '周一': '0 0 * * 1',
        '星期一': '0 0 * * 1',
        'tuesday': '0 0 * * 2',
        '周二': '0 0 * * 2',
        '星期二': '0 0 * * 2',
        'wednesday': '0 0 * * 3',
        '周三': '0 0 * * 3',
        '星期三': '0 0 * * 3',
        'thursday': '0 0 * * 4',
        '周四': '0 0 * * 4',
        '星期四': '0 0 * * 4',
        'friday': '0 0 * * 5',
        '周五': '0 0 * * 5',
        '星期五': '0 0 * * 5'
    };

    // 执行任务的核心逻辑
    async function executeTask() {
        try {
            const config = await readData();
            const thirdPartyData = await callThirdPartyApi(config.thirdParty);
            await callItaApi(config.ita, thirdPartyData);
        } catch (error) {
            console.error('任务执行期间发生错误:', error);
        }
    }

    // 立即执行一次
    await executeTask();

    // 设置定时任务
    const normalizedCycle = config.callCycle.toLowerCase();
    const cronExpression = CYCLE_MAP[normalizedCycle];

    if (!cronExpression) {
        console.error('不支持的调用周期:', config.callCycle);
        return;
    }
    // 启动定时任务
    cron.schedule(cronExpression, executeTask);
}
// 获取保存的数据
app.get('/data', async (req, res) => {
    try {
        const data = await readData();
        res.send(data);
    } catch (error) {
        res.status(500).send({ error: '无法读取数据' });
    }
});

// 保存新的数据
app.post('/data', async (req, res) => {
    try {
        await writeData(req.body);
        res.send({ success: true });
    } catch (error) {
        res.status(500).send({ error: '无法保存数据' });
    }
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, async () => {
    console.log(`Server is running on port ${PORT}`);
    // 读取配置并启动定时任务
    const config = await readData();
    scheduleTasks(config);
});